﻿using System;
using System.Collections.Generic;

namespace Fennec
{
    public class Carte
    {
        public int nombre_joueurs { get; private set; }
        public Case[,] cases { get; private set; } // TODO private : laissé tel quel pour l'ihm
        public ECarteTaille taille;

        // cases sur lesquelles un joueur peut installer ses premières unités
        private System.Drawing.Point[,] spawn_points;

        // Connstructeur vide pour tester IHM [TEMPORAIRE]
            public Carte()
            { }

        public Carte(ECarteTaille t, int nombre_joueurs)
        {
            taille = t;
            this.nombre_joueurs = nombre_joueurs;

            /* génération de la carte avec LibCarte (C++) */
            LibCarte.Carte carte = LibCarte.LibCarteWrapper.Carte_New();
            carte.setNbTypesCases(3);
            carte.setNbRessourcesSpeciales(2);
            switch (t)
            {
                case ECarteTaille.CARTE_TAILLE_NORMALE:
                    carte.setTaille(LibCarte.TailleCarte.TAILLE_NORMALE);
                    break;
                default:
                case ECarteTaille.CARTE_TAILLE_PETITE:
                    carte.setTaille(LibCarte.TailleCarte.TAILLE_PETITE);
                    break;
            }
            carte.setNbJoueurs(nombre_joueurs);
            carte.generer();

            /* importation des cases */
            this.cases = new Case[carte.getCote(), carte.getCote()];
            for (int i = 0; i < carte.getCote(); i++)
            {
                for (int j = 0; j < carte.getCote(); j++)
                {
                    LibCarte.Case cur = carte.getCase(i, j);
                    Case case_brute;
                    switch ((ECaseType) cur.type)
                    {
                        case ECaseType.CASE_DESERT:
                            case_brute = new CaseDésert();
                            break;
                        case ECaseType.CASE_MONTAGNE:
                            case_brute = new CaseMontagne();
                            break;
                        case ECaseType.CASE_PLAINE:
                            case_brute = new CasePlaine();
                            break;
                        default:
                            // TODO exception
                            case_brute = null;
                            break;
                    }
                    switch ((ECaseRessourceSpéciale)cur.ressource_speciale)
                    {
                        case ECaseRessourceSpéciale.CASE_FER:
                            this.cases[i, j] = new CaseFer(case_brute);
                            break;
                        case ECaseRessourceSpéciale.CASE_FRUIT:
                            this.cases[i, j] = new CaseFruit(case_brute);
                            break;
                        default:
                        case ECaseRessourceSpéciale.CASE_SANS_RESSOURCE_SPECIALE:
                            this.cases[i, j] = case_brute;
                            break;
                    }
                }
            }

            /* importation des spawn points */
            this.spawn_points = new System.Drawing.Point[this.nombre_joueurs,
                            LibCarte.LibCarteWrapper.NB_SPAWN_POINTS_PAR_JOUEUR];
            for (int i = 0; i < this.nombre_joueurs; i++)
            {
                LibCarte.vector_point2d sp = carte.getSpawnPoints(i);
                for (int j = 0; j < LibCarte.LibCarteWrapper.NB_SPAWN_POINTS_PAR_JOUEUR; j++)
                {
                    this.spawn_points[i, j].X = sp[j].x;
                    this.spawn_points[i, j].Y = sp[j].y;
                }
            }
        }

        public System.Drawing.Point getDimensions()
        {
            int c = 0;
            switch (this.taille)
            {
                case ECarteTaille.CARTE_TAILLE_PETITE:
                    c = 25;
                    break;
                case ECarteTaille.CARTE_TAILLE_NORMALE:
                    c = 40;
                    break;
            }
            return new System.Drawing.Point(c, c);
        }

        public bool estCaseValide(System.Drawing.Point position)
        {
            return position.X >= 0 && position.X < this.cases.Length
                && position.Y >= 0 && position.Y < this.cases.Length;
        }

        public Case getCase(System.Drawing.Point position)
        {
            return this.cases[position.X,position.Y];
        }

        public System.Drawing.Point[] getSpawnPoints(int joueur_id)
        {
            System.Drawing.Point[] res = new System.Drawing.Point[LibCarte.LibCarteWrapper.NB_SPAWN_POINTS_PAR_JOUEUR];
            for (int i = 0; i < res.Length; i++)
            {
                res[i] = this.spawn_points[joueur_id, i];
            }
            return res;
        }
    }
}